package com.hyopt.common.utils;

import com.google.common.annotations.Beta;

import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

/**
 * todo 封装各种生成唯一性ID算法的工具类.
 *
 * @author crazypenguin
 * @version 1.0
 * @created 2017/7/26
 */
@Beta
public class SimpleIdUtils {

	private static SecureRandom random = new SecureRandom();

	/**
	 * 封装JDK自带的UUID, 通过Random数字生成, 中间有-分割.
	 */
	public static String getUUIDWithLine() {
		return UUID.randomUUID().toString();
	}

	/**
	 * 封装JDK自带的UUID, 通过Random数字生成, 中间无-分割.
	 */
	public static String getUUIDNoLine() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	/**
	 *
	 * @param machineId 分布式各台机器的id
	 * @return
	 */
	public static String genId(String machineId){
		String orderId =
				machineId +
						(System.currentTimeMillis() + "").substring(1) +
						(System.nanoTime() + "").substring(7, 10);
		return orderId;
	}

	public static String getOrderIdByUUId(String machineId) {

		int hashCodeV = UUID.randomUUID().toString().hashCode();
		if (hashCodeV < 0) {//有可能是负数
			hashCodeV = -hashCodeV;
		}
		// 0 代表前面补充0
		// 4 代表长度为4
		// d 代表参数为正数型
		String orderId=machineId + String.format("%015d", hashCodeV);
		return orderId;
	}

	public static String getOrderIdByTime() {
		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
		String newDate=sdf.format(new Date());
		String result="";
 		Random random=new Random();
		for(int i=0;i<3;i++){
			result+=random.nextInt(10);
		}
		return newDate+result;
	}

	/**
	 * 锁对象，可以为任意对象
	 */
	private static Object lockObj = "lockerOrder";
	/**
	 * 订单号生成计数器
	 */
	private static long orderNumCount = 0L;
	/**
	 * 每毫秒生成订单号数量最大值
	 */
	private int maxPerMSECSize=1000;


	/**
	 * 生成非重复订单号，理论上限1毫秒1000个，可扩展
	 * @param tname 测试用
	 */
	public void makeOrderNum(String tname) {
		try {
			// 最终生成的订单号
			String finOrderNum = "";
			synchronized (lockObj) {
				// 取系统当前时间作为订单号变量前半部分，精确到毫秒
				long nowLong = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
				// 计数器到最大值归零，可扩展更大，目前1毫秒处理峰值1000个，1秒100万
				if (orderNumCount >= maxPerMSECSize) {
					orderNumCount = 0L;
				}
				//组装订单号
				String countStr=maxPerMSECSize +orderNumCount+"";
				finOrderNum=nowLong+countStr.substring(1);
				orderNumCount++;
				System.out.println(finOrderNum + "--" + Thread.currentThread().getName() + "::" + tname );
				// Thread.sleep(1000);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成订单号
	 * uuid: db30cc85-3387-4845-87bc-dc390b55b7ea 前8位 + 201508171108900(yyMMddHHMMSS)
	 * 即： db30cc85201508171108900
	 *
	 * @return
	 */
	public static  String getOrderNo(){
		String orderNo = "" ;
		UUID uuid = UUID.randomUUID();
		String trandNo = String.valueOf((Math.random() * 9 + 1) * 1000000);
		String sdf = new SimpleDateFormat("yyyyMMddHHMMSS").format(new Date());
		orderNo = uuid.toString().substring(0, 8);
		orderNo = orderNo + sdf ;
		return orderNo ;
	}


	/*
	* 核销码
	* */
	public static  String getVerificationCode(String orderSn){
		Random random = new Random();
		SimpleDateFormat allTime = new SimpleDateFormat("YYYYMMddHHmmSSS");
		String subjectno = allTime.format(new Date()).substring(8,14)+random.nextInt(10);
		return random.nextInt(10)+subjectno+orderSn.substring(orderSn.length()-5,orderSn.length()-1);
	}

	public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f",
			"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
			"t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
			"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
			"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
			"W", "X", "Y", "Z" };


	/**
	 * 短8位UUID
	 * @return
	 */
	public static String generateShortUuid() {
		StringBuffer shortBuffer = new StringBuffer();
		String uuid = UUID.randomUUID().toString().replace("-", "");
		for (int i = 0; i < 8; i++) {
			String str = uuid.substring(i * 4, i * 4 + 4);
			int x = Integer.parseInt(str, 16);
			shortBuffer.append(chars[x % 0x3E]);
		}
		return shortBuffer.toString();
	}

	public static void main(String[] args) {
		// System.out.println(getOrderIdByUUId("1"));
		// 测试多线程调用订单号生成工具
//		try {
//			for (int i = 0; i < 200; i++) {
//				Thread t1 = new Thread(new Runnable() {
//					public void run() {
//						SimpleIdUtils makeOrder = new SimpleIdUtils();
//						makeOrder.makeOrderNum("a");
//					}
//				}, "at" + i);
//				t1.start();
//
//				Thread t2 = new Thread(new Runnable() {
//					public void run() {
//						SimpleIdUtils makeOrder = new SimpleIdUtils();
//						makeOrder.makeOrderNum("b");
//					}
//				}, "bt" + i);
//				t2.start();
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}

//		String A = getVerificationCode("20190215095752937");
//		System.out.println(getVerificationCode("20190215095752937"));
//		System.out.println(getOrderNo());
		String x = getOrderIdByTime();
		System.out.println(x.substring(5,x.length()));
	}
}
